import 'dart:async';

import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_nb_net/flutter_net.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:tracker/common/enums/get_sms_code_click_type.dart';
import 'package:tracker/common/enums/user_type_enum.dart';
import 'package:tracker/common/log/x_logger.dart';
import 'package:tracker/pages/login/model/login_resp.dart';
import 'package:tracker/pages/login/model/verification_code_resp.dart';
import 'package:tracker/provider/global_provider.dart';
import 'package:tracker/router/router_manager.dart';
import 'package:tracker/theme/app_theme.dart';
import 'package:tracker/utils/toast_utils.dart';

/// 点击的按钮类型
final bindPhoneClickButtonTypeProvider = StateProvider<GetSmsCodeClickType>((ref) {
  return GetSmsCodeClickType.getCode;
});

/// 倒计时时间
final countdownTimeProvider = StateProvider<int>((ref) {
  return 0;
});

/// 绑定手机 页面
class BindPhonePage extends ConsumerStatefulWidget {
  const BindPhonePage({super.key});

  @override
  ConsumerState<BindPhonePage> createState() => _BindPhonePageState();
}

class _BindPhonePageState extends ConsumerState<BindPhonePage> {
  final _formKey = GlobalKey<FormState>();
  final _phoneController = TextEditingController();
  final _codeController = TextEditingController();
  final textColor = Colors.black;
  Timer? _countdownTimer;
  final _countdownTime = 60;
  var _uuid = '';

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
    super.initState();
  }

  // Widget绘制完成后的回调
  void _afterLayout(Duration timeStamp) {
    ref.read(countdownTimeProvider.notifier).state = 0;
  }

  /// 获取验证码
  _fetchCode() async {
    ToastUtils.showLoading();
    var res = await post<VerificationCodeResp, VerificationCodeResp>('/app/user/getSmsCode',
        data: {'phone': _phoneController.text}, decodeType: VerificationCodeResp());
    res.when(success: (resp) {
      ToastUtils.dismissLoading();
      if (resp.code == 200) {
        ToastUtils.showSuccess('验证码已发送');
        _uuid = resp.data!.uuid!;
        // 开始倒计时60秒
        ref.read(countdownTimeProvider.notifier).state = _countdownTime;
        _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
          ref.read(countdownTimeProvider.notifier).state = ref.read(countdownTimeProvider) - 1;
          if (timer.tick >= _countdownTime) {
            timer.cancel();
            ref.read(bindPhoneClickButtonTypeProvider.notifier).state = GetSmsCodeClickType.getCode;
          }
        });
      }
    }, failure: (String msg, int code) {
      XLogger.error('获取验证码失败 code: $code msg: $msg');
    });
  }

  /// 绑定手机
  _bindPhone() async {
    final bindPhoneData = {
      'phone': _phoneController.text,
      'code': _codeController.text,
      'uuid': _uuid,
      'imei': SpUtil.getString('tempLoginImei')
    };
    ToastUtils.showLoading();
    var res = await post<LoginResp, LoginResp>('/app/user/bindPhone', data: bindPhoneData, decodeType: LoginResp());
    res.when(success: (resp) {
      ToastUtils.dismissLoading();
      if (resp.code == 200) {
        // 绑定成功，保存登录信息
        SpUtil.putObject('loginData', resp.data!);
        SpUtil.putBool('isLogin', true);
        SpUtil.putBool('needChangePassword', true);
        ref.read(userTypeProvider.notifier).state = UserTypeEnum.fromValue(resp.data!.type!);
        // 修改密码
        // 2024-03-06 绑定手机号后不需要修改密码
        // context.push(RouterManager.changePassword);
        ToastUtils.showSuccess('登录成功');
        // 延迟1秒跳转
        Future.delayed(const Duration(seconds: 1), () {
          context.go('/');
        });
      } else {
        ToastUtils.showToast(resp.msg ?? '绑定失败');
      }
    }, failure: (String msg, int code) {
      XLogger.error('绑定失败 code: $code msg: $msg');
    });
  }

  @override
  void dispose() {
    _countdownTimer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final clickButtonType = ref.watch(bindPhoneClickButtonTypeProvider);
    final countdownTime = ref.watch(countdownTimeProvider);

    return Scaffold(
      appBar: AppBar(
        // 返回按钮的颜色
        iconTheme: const IconThemeData(color: Colors.black),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            // 标题
            Container(
              alignment: Alignment.topLeft,
              margin: const EdgeInsets.only(
                left: 20,
              ),
              child: const Text(
                '绑定手机',
                style: TextStyle(
                  fontSize: 24,
                ),
              ),
            ),
            // 提示
            Container(
              alignment: Alignment.topLeft,
              margin: const EdgeInsets.only(
                left: 20,
              ),
              child: Text(
                '绑定手机后，您可以使用手机号登录',
                style: TextStyle(
                  fontSize: 15,
                  color: AppTheme.themeConfig.infoTextColor,
                ),
              ),
            ),
            const SizedBox(
              height: 60,
            ),
            // 表单
            Container(
              margin: const EdgeInsets.only(left: 20, right: 20),
              child: Form(
                key: _formKey,
                child: Column(
                  children: [
                    // 手机号码
                    TextFormField(
                      controller: _phoneController,
                      style: TextStyle(color: textColor),
                      decoration: InputDecoration(
                        hintText: "请输入手机号码",
                        hintStyle: TextStyle(
                          fontSize: 15,
                          color: AppTheme.themeConfig.infoTextColor,
                        ),
                        // 调整内边距
                        contentPadding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 16.0),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(32),
                        ),
                        focusedBorder: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(32),
                          borderSide: BorderSide(
                            color: AppTheme.themeConfig.primaryColor,
                          ),
                        ),
                      ),
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return '请输入手机号码';
                        }
                        // 手机号正则校验
                        RegExp exp = RegExp(r"^1[3456789]\d{9}$");
                        if (!exp.hasMatch(value)) {
                          return '请输入正确的手机号码';
                        }
                        return null;
                      },
                      inputFormatters: [
                        // 只允许输入数字
                        FilteringTextInputFormatter.allow(RegExp('[0-9]')),
                        // 限制输入为11个数字
                        LengthLimitingTextInputFormatter(11),
                      ],
                      // 数字键盘
                      keyboardType: TextInputType.number,
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    Stack(
                      children: [
                        TextFormField(
                          controller: _codeController,
                          style: TextStyle(color: textColor),
                          decoration: InputDecoration(
                            hintText: "请输入验证码",
                            hintStyle: TextStyle(
                              fontSize: 15,
                              color: AppTheme.themeConfig.infoTextColor,
                            ),
                            // 调整内边距
                            contentPadding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 16.0),
                            border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(32),
                            ),
                            focusedBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(32),
                              borderSide: BorderSide(
                                color: AppTheme.themeConfig.primaryColor,
                              ),
                            ),
                          ),
                          validator: (value) {
                            // 点击验证码按钮时，不校验
                            if (clickButtonType == GetSmsCodeClickType.getCode) {
                              return null;
                            }
                            if (value == null || value.isEmpty) {
                              return '请输入验证码';
                            }
                            return null;
                          },
                          inputFormatters: [
                            // 只允许输入数字
                            FilteringTextInputFormatter.allow(RegExp('[0-9]')),
                            // 限制输入为6个数字
                            LengthLimitingTextInputFormatter(6),
                          ],
                          // 数字键盘
                          keyboardType: TextInputType.number,
                        ),
                        // 获取验证码
                        Positioned(
                          right: 0,
                          child: GestureDetector(
                            onTap: () {
                              // 倒计时未结束时，不允许点击
                              if (countdownTime > 0) {
                                return;
                              }
                              // 校验手机号码
                              ref.read(bindPhoneClickButtonTypeProvider.notifier).state = GetSmsCodeClickType.getCode;
                              if (_formKey.currentState!.validate()) {
                                // 获取验证码
                                _fetchCode();
                              }
                            },
                            child: Container(
                              alignment: Alignment.center,
                              width: 120,
                              height: 56,
                              decoration: BoxDecoration(
                                // color: AppTheme.themeConfig.primaryColor,
                                borderRadius: BorderRadius.circular(28),
                              ),
                              child: _buildCodeText(),
                            ),
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    // 绑定按钮
                    SizedBox(
                      width: double.infinity,
                      height: 50,
                      child: ElevatedButton(
                        onPressed: () {
                          ref.read(bindPhoneClickButtonTypeProvider.notifier).state = GetSmsCodeClickType.submit;
                          // 校验表单
                          if (_formKey.currentState!.validate()) {
                            // 验证通过提交数据
                            _bindPhone();
                          }
                        },
                        style: ButtonStyle(
                          shape: MaterialStateProperty.all(
                            RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(32),
                            ),
                          ),
                          backgroundColor: MaterialStateProperty.all(AppTheme.themeConfig.primaryColor),
                        ),
                        child: const Text(
                          "绑定",
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Text _buildCodeText() {
    final downTime = ref.watch(countdownTimeProvider);
    if (downTime > 0) {
      return Text(
        '${downTime}s后重新获取',
        style: TextStyle(
          fontSize: 15,
          color: AppTheme.themeConfig.infoTextColor,
        ),
      );
    } else {
      return Text(
        '获取验证码',
        style: TextStyle(
          fontSize: 15,
          color: AppTheme.themeConfig.primaryColor,
        ),
      );
    }
  }
}
